/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package scheduler.view;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.stage.Stage;
import javafx.util.Callback;
import scheduler.core.PoolProcessor;
import scheduler.core.TaskProcessor;
import scheduler.core.task.Taskj;
import scheduler.core.task.VirtualTaskPool;
import scheduler.core.utils.TaskPoolValidationException;
import scheduler.core.utils.TaskjValidationException;
import scheduler.core.utils.ValidationException;
import scheduler.view.cells.TaskjCell;
import scheduler.view.cells.VirtualPoolCell;
import scheduler.view.dialogs.DialogUtils;

/**
 * FXML Controller class
 *
 * @author Dima
 */
public class WindowController implements Initializable {
    
    @FXML
    private ChoiceBox priorityNum;
    @FXML
    private Button addTask;
    @FXML
    private Button editTask;
    @FXML
    private Button removeTask;
    @FXML
    private Button calculate;
    @FXML
    private ListView taskList;
    @FXML
    private ChoiceBox priorityNum2;
    @FXML
    private Button addTask2;
    @FXML
    private Button editTask2;
    @FXML
    private Button removeTask2;
    @FXML
    private Button calculate2;
    @FXML
    private ListView taskList2;
    private TaskProcessor taskProcessor;
    private PoolProcessor poolProcessor;
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        taskList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        priorityNum.getSelectionModel().select(5);
        taskList2.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        priorityNum2.getSelectionModel().select(5);
        taskList.setCellFactory(new Callback<ListView<Taskj>, ListCell<Taskj>>() {
            @Override
            public ListCell<Taskj> call(ListView<Taskj> p) {
                return new TaskjCell();
            }
        });
        taskList2.setCellFactory(new Callback<ListView<VirtualTaskPool>, ListCell<VirtualTaskPool>>() {

            @Override
            public ListCell<VirtualTaskPool> call(ListView<VirtualTaskPool> p) {
                return new VirtualPoolCell();
            }

        }); 
        
        
    }
    @FXML
    private void onCloseClick(ActionEvent event) throws IOException {
        Stage stage = (Stage) addTask.getScene().getWindow();
        stage.close();
    }
    
    @FXML
    private void onExample1Click(ActionEvent event) throws IOException {
        try {
            taskList.getItems().clear();
            Taskj.dropIdCounter();
            taskList2.getItems().clear();
            taskList.getItems().add(new Taskj(1,1.0, 0.1));
            taskList.getItems().add(new Taskj(1, 3.0, 0.1));
            taskList.getItems().add(new Taskj(2, 2.0, 0.05));
            taskList.getItems().add(new Taskj(2, 2.0, 0.15));
            taskList.getItems().add(new Taskj(3, 0.5, 0.12));
            taskList.getItems().add(new Taskj(3, 3.5, 0.08));
            taskList2.getItems().add(new VirtualTaskPool(1, 2, 2, 0.1));
            taskList2.getItems().add(new VirtualTaskPool(2, 2, 2, 0.1));
            taskList2.getItems().add(new VirtualTaskPool(3, 2, 2, 0.1));
        } catch (TaskjValidationException | TaskPoolValidationException ex) {
            Logger.getLogger(WindowController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    @FXML
    private void onAddTaskClick(ActionEvent event) throws IOException {
        Taskj task = DialogUtils.showTaskCreator(Integer.valueOf((String)priorityNum.getSelectionModel().getSelectedItem()));

        if (task != null) {
            taskList.getItems().add(task);
        }
    }
    
    @FXML
    private void onEditTaskClick(ActionEvent event) throws IOException {
        int index = taskList.getSelectionModel().getSelectedIndex();
        
        if (index == -1) {
            DialogUtils.showErrorDialog("Виберіть задачу для редагування.");
            return;
        }
        
        Taskj task = (Taskj) taskList.getItems().get(index);
        Taskj editedTask = DialogUtils.showTaskCreator(task, Integer.valueOf((String)priorityNum.getSelectionModel().getSelectedItem()));
        
        if (editedTask != null) {
            taskList.getItems().remove(index);
            taskList.getItems().add(index, editedTask);
        }
    }
    
    @FXML
    private void onRemoveTaskClick(ActionEvent event) throws IOException, TaskjValidationException {
        int index = taskList.getSelectionModel().getSelectedIndex();
        
        if (index == -1) {
            DialogUtils.showErrorDialog("Виберіть задачу для видалення.");
            return;
        }
        Taskj task = (Taskj) taskList.getItems().remove(index);


    }
    
    @FXML
    private void onCalculateClick(ActionEvent event) throws IOException {
        try {
            taskProcessor = new TaskProcessor(Integer.valueOf((String)priorityNum.getSelectionModel().getSelectedItem()), taskList.getItems());
            if(taskList.getItems().isEmpty()){
                DialogUtils.showErrorDialog("Список задач не може бути пустим.");
            }else {
                DialogUtils.showResultsWindow(taskProcessor);
            }
        } catch (TaskPoolValidationException | TaskjValidationException | ValidationException ex) {
            DialogUtils.showErrorDialog(ex.getMessage());
        }
    }
    
    @FXML
    private void onAddTaskClick2(ActionEvent event) throws IOException, TaskPoolValidationException {
        int numOfPriors = Integer.parseInt((String)priorityNum2.getSelectionModel().getSelectedItem());
        int size = taskList2.getItems().size();
        VirtualTaskPool pool = null;
        
        if (numOfPriors > taskList2.getItems().size()) {
            pool = DialogUtils.showPoolCreator(size + 1);
        }
        
        if (pool != null) {   
            taskList2.getItems().add(pool);
            return;
        }
        if(numOfPriors <= taskList2.getItems().size()){
            if(numOfPriors == 10){
                DialogUtils.showErrorDialog("Cтворено максимальну кількість пулів задач - 10. Додати новий пул не можливо.");
                return;
            }
            DialogUtils.showErrorDialog("Для створення нового пулу задач потрібно збітьшити кількість пріоритетів.");
        }
        
    }
    
    @FXML
    private void onEditTaskClick2(ActionEvent event) throws IOException, TaskPoolValidationException {
        int index = taskList2.getSelectionModel().getSelectedIndex();
        int size = taskList2.getItems().size();
        if (index == -1) {
            DialogUtils.showErrorDialog("Виберіть пул задач для редагування.");
            return;
        }
        VirtualTaskPool task = (VirtualTaskPool) taskList2.getItems().get(index);
        VirtualTaskPool editedTask = DialogUtils.showPoolCreator(task, size);
        
        if (editedTask != null) {
            taskList2.getItems().remove(index);
            taskList2.getItems().add(index, editedTask);
        }
    }
    
    private void shiftPool(int index, int newIndex) throws TaskPoolValidationException {
        if (newIndex < index) {
            for (int i = newIndex + 1; i <= index; ++i) {
                ((VirtualTaskPool)taskList2.getItems().get(i)).setPrior(i + 1);
                VirtualTaskPool pool = (VirtualTaskPool) taskList2.getItems().remove(i);
                taskList2.getItems().add(i, pool);
            }
        } else {
            for (int i = index; i < newIndex; ++i) {
                ((VirtualTaskPool)taskList2.getItems().get(i)).setPrior(i + 1);
            }
        }
    }
    
    @FXML
    private void onRemoveTaskClick2(ActionEvent event) throws IOException, TaskjValidationException, TaskPoolValidationException {
        int index = taskList2.getSelectionModel().getSelectedIndex();
        
        if (index == -1) {
            return;
        }
        taskList2.getItems().remove(index);
        for(int i = index; i < taskList2.getItems().size(); i++){
            ((VirtualTaskPool)taskList2.getItems().get(i)).setPrior(i + 1);
        }
    }
    
    @FXML
    private void onCalculateClick2(ActionEvent event) throws IOException {
        
        try {
            poolProcessor = new PoolProcessor(Integer.valueOf((String)priorityNum2.getSelectionModel().getSelectedItem()), taskList2.getItems());
            if(taskList2.getItems().isEmpty()){
                DialogUtils.showErrorDialog("Список черг задач не може бути пустим.");
            }else {
                DialogUtils.showResultsWindow(poolProcessor);
            }
        } catch (TaskPoolValidationException | ValidationException ex) {
            DialogUtils.showErrorDialog(ex.getMessage());
        }
    }
}
